home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Multimedia / Resource Library: Multimedia.iso / _archive / archivrs / msdos / bzip.zoo / bzip.c next >
C/C++ Source or Header  |  1992-07-18  |  13KB  |  613 lines

  1. /* this is a little utility used 
  2.    to backup files compressed by pkzip to a disk
  3.  
  4.    the first argument is the name of the diskdrive to use for backup
  5.  
  6.    if no other arguments are given:
  7.  
  8.      it first compresses all files in the current directory (which can
  9.      be the root) to a file root.zip and stores this file to disk
  10.  
  11.      then it compresses all directories, one by one, and stores these
  12.      to disk
  13.  
  14.    if other arguments are given they are compressed one by one and stored
  15.    to disk
  16.  
  17.    when storing a zipped file, it splits the file into parts on separate
  18.    disks if necessary. These parts are called name.p#  where # is a
  19.    number from 1 to 99. The last part is called name.-#
  20.    They can easily be restored.
  21.  
  22.    normally the program signals only when it needs a new disk.
  23.    it deletes anything on the disk and calls a format program if necessary
  24.  
  25. */
  26. #include <time.h>
  27. #include <conio.h>
  28. #include <dos.h>
  29. #include <dir.h>
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include <ctype.h>
  33. #include <fcntl.h>
  34. #include <alloc.h>
  35. #include <io.h>
  36. #include <errno.h>
  37. #include <sys\stat.h>
  38.  
  39. #define true 1
  40. #define false 0
  41.  
  42.  
  43. #define ROOTFILES 1
  44. #define DIRFILES 2
  45. #define SINGLEFILE 3
  46.  
  47.  
  48. int dnum = 0; /* current backup disk */
  49.  
  50. char zipdir[64];
  51. char zipname[128];
  52. char zipsname[18];
  53.  
  54. char cmdline[128];
  55. char drive = 'A';
  56. char *buf;
  57.  
  58. typedef struct his {char s[128]; struct his * n;} his;
  59.  
  60. struct his * history = NULL, *th;
  61.  
  62. char bleepkey()
  63. {
  64.   time_t tp, tn;
  65.  
  66.   while(! kbhit()){
  67.     sound(600);delay(100);nosound();delay(100);
  68.     sound(600);delay(100);nosound();delay(100);
  69.     sound(600);delay(100);nosound();delay(100);
  70.     sound(860);delay(400);nosound();
  71.  
  72.     (void) time(&tp);
  73.  
  74.     do (void)time(&tn); while((! kbhit()) && (tn - tp < 4));
  75.   }
  76.   return getch();
  77. }
  78.  
  79.  
  80. int askcontin()
  81. {
  82.   char c;
  83.  
  84.   for(;;){
  85.     fprintf(stdout, "Continue? (n)o [y]es ");
  86.     c = bleepkey();
  87.     switch(c){
  88.       case 10: case 13: case 'y': case 'Y': puts("YES"); return true;
  89.       case 'n': case 'N': puts("NO"); return false;
  90.       otherwise: break;
  91.     }
  92.   }
  93. }
  94.  
  95. void deletedir(char *path){
  96.   char spath[128];
  97.   char npath[128];
  98.   struct ffblk fs;
  99.  
  100.   strcpy(spath, path);
  101.   strcat(spath, "*.*");
  102.  
  103.   if(findfirst(spath, &fs, FA_DIREC) == 0){
  104.     do{
  105.       if(fs.ff_attrib & FA_DIREC){
  106.     if(fs.ff_name[0] != '.'){
  107.       strcpy(npath, path);
  108.       strcat(npath, fs.ff_name);
  109.       strcat(npath, "\\");
  110.       deletedir(npath);
  111.       strcpy(npath, path);
  112.       strcat(npath, fs.ff_name);
  113.       puts(npath);
  114.       if(rmdir(npath) != 0) perror("Ignored delete directory error: ");
  115.     }
  116.       }
  117.       else{
  118.     strcpy(npath, path);
  119.     strcat(npath, fs.ff_name);
  120.     puts(npath);
  121.     if(remove(npath)!= 0) if(errno == EACCES){
  122.       chmod(npath, S_IREAD | S_IWRITE);
  123.       if(remove(npath) != 0) perror("Ignored delete file error: ");
  124.     }
  125.       }
  126.     }while(findnext(&fs) == 0);
  127.   }
  128. }
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136. void cleandisk(){
  137.   char spath[10];
  138.  
  139.   struct ffblk fs;
  140.  
  141.   strcpy(spath, "x:\\*.*");
  142.   spath[0] = drive;
  143.  
  144.   if(findfirst(spath, &fs, FA_DIREC) == 0){
  145.     fprintf(stdout, "Deleting existing files %s\n", spath);
  146.     strcpy(spath, "x:\\");
  147.     spath[0] = drive;
  148.     deletedir(spath);
  149.   }
  150. }
  151.  
  152. int getinsertnew(){
  153.   char c;
  154.  
  155.   char fcmd[20];
  156.   char t[3];
  157.  
  158.  
  159.   dnum++;
  160.  
  161.   strcpy(fcmd, "format ");
  162.   strcpy(t, "x:");
  163.   t[0] = drive;
  164.   strcat(fcmd, t);
  165.  
  166.  
  167.   for(;;){
  168.     fprintf(stdout, "Insert new backup disk %d in drive %c\nALL EXISTING FILES WILL BE DELETED\n", dnum, drive);
  169.     fprintf(stdout, "Enter (f)ormat (s)top [c]ontinue ");
  170.  
  171.     c = bleepkey();
  172.  
  173.     switch(c){
  174.       case 'f': case 'F': puts("FORMAT"); system(fcmd); break;
  175.       case 's': case 'S': puts("STOP"); return false;
  176.       case 13: case 10: case 'c': case 'C': puts("CONTINUE"); cleandisk(); return true;
  177.     }
  178.   }
  179. }
  180.  
  181.  
  182. long df()
  183. {
  184.   int cnt = false;
  185.   int dr;
  186.   struct dfree free;
  187.  
  188.    /* we need to know drive free space */
  189.  
  190.   dr = (int)(drive - 'A') + 1;
  191.  
  192.   do{
  193.     getdfree(dr, &free);
  194.     if(free.df_sclus == 0xFFFF){
  195.       fprintf(stderr, "Can not get drive free space for %c\n", drive);
  196.       cnt = askcontin();
  197.       if(!cnt) return -1L;
  198.     }
  199.   }while(cnt);
  200.  
  201.   return (long) free.df_avail
  202.          * (long) free.df_bsec
  203.      * (long) free.df_sclus;
  204. }
  205.  
  206. #define maxbuf 16384
  207.  
  208. int splitcopy()
  209. {
  210.   long avail, filelen, r, w, wrote = 0L, readd = 0L;
  211.   int fn = 0;  int zf, czf, ctrl;
  212.   char t[4];
  213.   char zipcopy[20];
  214.  
  215.   /* we need to know length of zipfile */
  216.  
  217.  
  218.  
  219.   zf = _open(zipname, O_RDONLY | O_BINARY);
  220.  
  221. /*  ctrl = ioctl(zf, 0);
  222.   ioctl(zf, 1, (ctrl | 0x20) & 0xff); */ /* no ^Z intervention! */
  223.  
  224.   if(zf < 0){
  225.     fprintf(stderr, "Can not open %s for reading\n", zipname);
  226.     exit(-1);
  227.   }
  228.  
  229.   filelen = filelength(zf);
  230.  
  231.   for(;;){
  232.     /* available on disk */
  233.     avail = df();
  234.  
  235.     /* if error */
  236.     if(avail < 0){
  237.       close(zf);
  238.       return false;
  239.     }
  240.  
  241.     if(avail == 0) if(! getinsertnew()){ close(zf); return false; }
  242.  
  243.     printf("Drive %c: has %ld bytes available\n", drive, avail);
  244.  
  245.  
  246.     strcpy(zipcopy, "x:\\");
  247.     zipcopy[0] = drive;
  248.     strcat(zipcopy, zipsname);
  249.  
  250.     if((fn == 0) && (filelen <= avail))
  251.       strcat(zipcopy, ".zip");
  252.     else{
  253.       if((filelen - readd) < avail)
  254.     strcat(zipcopy, ".-");
  255.       else
  256.     strcat(zipcopy, ".p");
  257.       fn++;
  258.       strcat(zipcopy, itoa(fn,t,10));
  259.     }
  260.  
  261.     fprintf(stdout, "Creating %s\n", zipcopy);
  262.  
  263.     th = (struct his*) malloc(sizeof(struct his));
  264.     if(th != NULL){
  265.       sprintf(th->s, "%3d %s\n", dnum, zipcopy);
  266.       th->n = history;
  267.       history = th;
  268.     }
  269.  
  270.     czf = open(zipcopy, O_CREAT | O_BINARY | O_RDWR /*, S_IFREG | S_IREAD | S_IWRITE*/ );
  271.  
  272.     if(czf < 0){
  273.       fprintf(stderr, "Can not open %s for writing\n", zipcopy);
  274.       exit(-1);
  275.     }
  276.  
  277.  
  278.     /* what to do with read/write errors??? */
  279.  
  280.     do{
  281.       r = _read(zf, buf, (avail > maxbuf ? maxbuf : avail));
  282.  
  283.       if(r < 0){
  284.     fprintf(stderr, "\nRead error");
  285.     exit(-1);
  286.       }
  287.  
  288.       w = 0L;
  289.       if(r > 0){
  290.     w = _write(czf, buf, r);
  291.     if(r != w){
  292.       fprintf(stderr, "\nWrite error");
  293.       exit(-1);
  294.     }
  295.       }
  296.  
  297.       avail -= w;
  298.       readd += r;
  299.       wrote += w;
  300.       fprintf(stdout, "\rWrote %ld of %ld", wrote, filelen);
  301.     }while((avail > 0L ) && (r == maxbuf));
  302.  
  303.     fprintf(stdout, "\n");
  304.  
  305.     _close(czf);
  306.  
  307.     if(readd == filelen) {
  308.       _close(zf);
  309.       return true;
  310.     }
  311.  
  312.     if(!getinsertnew()){
  313.       close(zf);
  314.       return false;
  315.     }
  316.   }
  317. }
  318.  
  319. int compcopy(char * name, int mode)
  320. {
  321.   char *t;
  322.   int rv;
  323.   struct ffblk fs;
  324.  
  325.   /* if first disk */
  326.   if(dnum == 0) if(!getinsertnew()) return false;
  327.  
  328.   /* extract zipname */
  329.   t = name;
  330.   while(*t) t++;
  331.   t--;
  332.   while((t > name) && (*t != '\\')) t--;
  333.  
  334.   strcpy(zipsname, t);
  335.   t = zipsname;
  336.   while(*t) t++;
  337.   while((t > zipsname) && (*t != '.') && (*t != '\\')) t--;
  338.   if(*t == '.') *t = 0;
  339.  
  340.   if(*zipdir){
  341.     strcpy(zipname, zipdir);
  342.     strcat(zipname, "\\");
  343.     strcat(zipname, zipsname);
  344.   }
  345.   else strcpy(zipname, zipsname);
  346.   strcat(zipname, ".zip");
  347.  
  348.   /* construct pkzip command */
  349.  
  350.   switch(mode){
  351.     case ROOTFILES:
  352.       strcpy(cmdline, "pkzip ");
  353.       strcat(cmdline, zipname);
  354.       strcat(cmdline, " *.*");
  355.       break;
  356.     case DIRFILES:
  357.       strcpy(cmdline, "pkzip -Pr ");
  358.       strcat(cmdline, zipname);
  359.       strcat(cmdline, " ");
  360.       strcat(cmdline, name);
  361.       strcat(cmdline, "\\*.*");
  362.       break;
  363.     case SINGLEFILE:
  364.       strcpy(cmdline, "pkzip ");
  365.       strcat(cmdline, zipname);
  366.       strcat(cmdline, " ");
  367.       strcat(cmdline, name);
  368.       break;
  369.   }
  370.  
  371.   rv = system(cmdline);
  372.  
  373.  
  374.   if(findfirst(zipname, &fs, 0) != 0){
  375.     fprintf(stdout, "No zipfile created! (possibly empty directory or disk full)\n");
  376.     return askcontin();
  377.   }
  378.   else if(rv != 0){
  379.     fprintf(stderr, "PKZIP returned error value %d\n", rv);
  380.     remove(zipname);
  381.     return askcontin();
  382.   }
  383.  
  384.   printf("Now  split-copy %s to %c:\n", zipname, drive);
  385.  
  386.   rv = splitcopy();
  387.  
  388.   if(remove(zipname)){
  389.     fprintf(stderr, "Fatal error: Can not remove %s\n", zipname);
  390.     exit(-1);
  391.   }
  392.  
  393.   return rv;
  394.  
  395. }
  396.  
  397.  
  398. void printhistory(struct his * history, FILE * t)
  399. {
  400.   if(history == NULL) return;
  401.   printhistory(history -> n,t);
  402.   fputs(history -> s, stdout);
  403.   fputs(history -> s, t);
  404. }
  405.  
  406.  
  407.  
  408.  
  409.  
  410.  
  411.  
  412.  
  413.  
  414. void main(argc, argv)
  415. int argc;
  416. char **argv;
  417. {
  418.   int fspecified = 0;
  419.   struct ffblk fs;
  420.  
  421.   buf = (char *) malloc(maxbuf);
  422.  
  423.   if(buf == NULL){
  424.     fprintf(stderr, "Can not allocate copy buffer, sorry ...");
  425.     exit(-1);
  426.   }
  427.  
  428.   strcpy(zipdir, ".");
  429.  
  430.   if((argc > 1) && (strcmp(argv[1], "-r") == 0)){
  431.     rzip( --argc, ++argv);
  432.     exit(0);
  433.   }
  434.  
  435.   argc--;
  436.   argv++;
  437.  
  438.  
  439.   while(argc--){
  440.     if(argv[0][0] == '-') switch(argv[0][1]){
  441.       case 'd':
  442.      if(strlen(argv) == 2){
  443.        fprintf(stderr, "Need directory name for -d switch\n");
  444.        exit(-1);
  445.      }
  446.      strcpy(zipdir, &argv[0][2]);
  447.          printf("Temporary directory for zipfiles is %s\n", zipdir); 
  448.      break;
  449.       otherwise: break;
  450.     }
  451.     else if((strlen(argv[0]) == 2) && (argv[0][1] == ':')){
  452.       drive = toupper(argv[0][0]);
  453.       if(drive > 'B'){
  454.     fprintf(stderr, "drive specification must one of A: or B:\n");
  455.     exit(-1);
  456.       }
  457.     }
  458.     else{
  459.       fspecified = true;
  460.       if(! findfirst(argv[0], &fs, FA_DIREC)){
  461.     if(fs.ff_attrib == FA_DIREC){
  462.       if(!compcopy(argv[0], DIRFILES)) exit(-1);
  463.     }
  464.     else if(!compcopy(argv[1], SINGLEFILE)) exit(-1);
  465.       }
  466.       else{
  467.     fprintf(stderr, "\007File not found %s\n", argv[0]);
  468.       }
  469.     }
  470.     argv++;
  471.   }
  472.  
  473.   if(! fspecified){
  474.     if(!compcopy("root", ROOTFILES)) exit(-1);
  475.     if(! findfirst("*.*", &fs, FA_DIREC)) do{
  476.       if((fs.ff_attrib == FA_DIREC) && (fs.ff_name[0] != '.'))
  477.     if(!compcopy(fs.ff_name, DIRFILES)) exit(-1);
  478.     }while(findnext(&fs) != -1);
  479.   }
  480.  
  481.   if(history != NULL){
  482.     char tn[20];
  483.     FILE *t;
  484.  
  485.     strcpy(tn, "x:\\BZIP.CNT");
  486.     *tn = drive;
  487.  
  488.     t = fopen(tn, "w");
  489.     if(t == NULL){
  490.       fprintf(stderr, "Cannot create table of contents file\n");
  491.       exit(-1);
  492.     }
  493.     fputs("\nTable of contents:\n\n", stdout);
  494.     fputs("Table of contents:\n\n", t);
  495.     printhistory(history, t);
  496.     fclose(t);
  497.     fprintf(stdout, "Table of contents written on %s\n", tn);
  498.   }
  499.   printf("Done, press a a key \n"); bleepkey();
  500. }
  501.  
  502.  
  503. /* ===============  source for rzip ============== */
  504.  
  505. rzip(argc,argv)
  506. int argc;
  507. char **argv;
  508. {
  509.   char c, spath[80], drive[3], dir[66], file[9], ext[5], npath[80], zipname[80], *t;
  510.   int fnum = 1, fc, fo, flags, lastfile = false;
  511.   int r, w;
  512.   long tw = 0L;
  513.   struct ffblk fs;
  514.  
  515.   if(argc != 2){
  516.     fprintf(stderr, "Usage: rzip drive:zipname\n");
  517.     exit(-1);
  518.   }
  519.  
  520.   strcpy(spath, argv[1]);
  521.  
  522.   flags = fnsplit(spath, drive, dir, file, ext);
  523.   if((flags & WILDCARDS) || (!(flags & FILENAME))){
  524.     fprintf(stderr, "Illegal filename: %s\n", spath);
  525.     exit(-1);
  526.   }
  527.  
  528.   strcpy(zipname, file);
  529.   strcat(zipname, ".zip");
  530.  
  531.   /* remove extension (if any) from specified name */
  532.   if(flags & EXTENSION)
  533.     spath[strlen(spath) - strlen(ext)] = 0;
  534.  
  535.   printf("Restoring split zipfile %s\n", zipname);
  536.  
  537.   fc = open(zipname, O_CREAT | O_BINARY | O_RDWR, S_IWRITE | S_IREAD);
  538.   if(fc < 0){
  539.     fprintf(stderr, "Cannot open zipfile %s\n", zipname);
  540.     exit(-1);
  541.   }
  542.  
  543.   for(;;){
  544.     do{
  545.       if(fnum == 1)
  546.     printf("Enter first disk: (a)bort [c]ontinue ");
  547.       else
  548.     printf("Enter next disk: (a)bort [c]ontinue ");
  549.       c = toupper(bleepkey());
  550.       switch(c){
  551.      case 10: case 13: case 'C': c= 'C'; puts("CONTINUE"); break;
  552.      case 'A': puts("ABORT"); close(fc); remove(zipname); exit(-1); break;
  553.       }
  554.     }while(c != 'C');
  555.  
  556.     do{
  557.       c = 'D';
  558.       sprintf(npath, "%s.-%d", spath, fnum);
  559.       if(findfirst(npath, &fs, 0) == 0)
  560.     lastfile = true;
  561.       else{
  562.     sprintf(npath, "%s.p%d", spath, fnum);
  563.     if(findfirst(npath, &fs, 0) != 0){
  564.       printf("\007File %s.[p-]%d not found (r)etry (a)bort", spath, fnum);
  565.       c = toupper(bleepkey());
  566.       switch(c){
  567.         case 'R': puts("RETRY"); break;
  568.         case 'A': puts("ABORT"); exit(-1); break;
  569.         otherwise: c = 'R'; break;
  570.       }
  571.     }
  572.       }
  573.     }while(c == 'R');
  574.  
  575.     printf("Copying %s to %s\n", npath, zipname);
  576.  
  577.     fnum++;
  578.     printf("Reading %s\n", npath);
  579.     fo = open(npath, O_RDONLY | O_BINARY);
  580.     if(fo < 0){
  581.       fprintf(stderr, "Can not open file %s\n", npath);
  582.       exit(-1);
  583.     }
  584.  
  585.     do{
  586.       r = _read(fo, buf, maxbuf);
  587.  
  588.       if(r > 0){
  589.     w = _write(fc, buf, r);
  590.     tw += w;
  591.     printf("\rWrote %ld", tw);
  592.     if(w < r){
  593.       fprintf(stderr, "\nwrite error on temporary zipfile");
  594.       close(fo);
  595.       close(fc);
  596.       remove(zipname);
  597.       exit(-1);
  598.     }
  599.       }
  600.     }while(r == maxbuf);
  601.     putchar('\n');
  602.  
  603.     close(fo);
  604.  
  605.     if(lastfile){
  606.       close(fc);
  607.       printf("DONE, Press a key\n");
  608.       bleepkey();
  609.       exit(0);
  610.     }
  611.   }
  612. }
  613.